package model

import (
	"errors"
	"fmt"
	"parking-lot-go-dingding/config"
	"reflect"
	"strings"

	"github.com/go-redis/redis"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var Db *gorm.DB
var err error
var RedisClient *redis.Client

func init() {

	// 数据库配置
	dbSection := config.Cfg.Section("DATABASE")
	dbHost := dbSection.Key("DB_HOST").String()
	dbPort := dbSection.Key("DB_PORT").String()
	dbName := dbSection.Key("DB_DATABASE").String()
	dbUsername := dbSection.Key("DB_USERNAME").String()
	dbPassword := dbSection.Key("DB_PASSWORD").String()

	dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		dbUsername, dbPassword, dbHost, dbPort, dbName)

	Db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})

	if err != nil {
		panic(err.Error())
	}

	//redis配置
	redisSection := config.Cfg.Section("REDIS")
	redisHost := redisSection.Key("HOST").String()
	redisPort := redisSection.Key("PORT").String()
	redisPassword := redisSection.Key("PASSWORD").String()
	redisDb, _ := redisSection.Key("DB").Int()

	// 创建 Redis 客户端实例
	RedisClient = redis.NewClient(&redis.Options{
		Addr:     fmt.Sprintf("%s:%s", redisHost, redisPort), // Redis 服务器地址
		Password: redisPassword,                              // Redis 服务器密码，如果没有密码则留空
		DB:       redisDb,                                    // 使用的数据库编号，默认为 0
	})
}

// /region 业务上扩展方法
// BuildWhere 构建where条件
func BuildWhere(where interface{}) (*gorm.DB, error) {
	db := Db

	t := reflect.TypeOf(where).Kind()
	if t == reflect.Struct || t == reflect.Map {
		db = db.Where(where)
	} else if t == reflect.Slice {
		for _, item := range where.([]interface{}) {
			item := item.([]interface{})
			column := item[0]
			if reflect.TypeOf(column).Kind() == reflect.String {
				count := len(item)
				if count == 1 {
					return nil, errors.New("切片长度不能小于2")
				}
				columnstr := column.(string)
				// 拼接参数形式
				if strings.Index(columnstr, "?") > -1 {
					db = db.Where(column, item[1:]...)
				} else {
					cond := "and" //cond
					opt := "="
					_opt := " = "
					var val interface{}
					if count == 2 {
						opt = "="
						val = item[1]
					} else {
						opt = strings.ToLower(item[1].(string))
						_opt = " " + strings.ReplaceAll(opt, " ", "") + " "
						val = item[2]
					}

					if count == 4 {
						cond = strings.ToLower(strings.ReplaceAll(item[3].(string), " ", ""))
					}

					/*
					   '=', '<', '>', '<=', '>=', '<>', '!=', '<=>',
					   'like', 'like binary', 'not like', 'ilike',
					   '&', '|', '^', '<<', '>>',
					   'rlike', 'regexp', 'not regexp',
					   '~', '~*', '!~', '!~*', 'similar to',
					   'not similar to', 'not ilike', '~~*', '!~~*',
					*/

					if strings.Index(" in notin ", _opt) > -1 {
						// val 是数组类型
						column = columnstr + " " + opt + " (?)"
					} else if strings.Index(" = < > <= >= <> != <=> like likebinary notlike ilike rlike regexp notregexp", _opt) > -1 {
						column = columnstr + " " + opt + " ?"
					}

					if cond == "and" {
						db = db.Where(column, val)
					} else {
						db = db.Or(column, val)
					}
				}
			} else if t == reflect.Map /*Map*/ {
				db = db.Where(item)
			}
		}
	} else {
		return nil, errors.New("参数有误")
	}
	return db, nil
}
